package com.goodsogood.union.auth.task.pool;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class UserDefaultThreadPool {

    private static class InstanceHolder {  
        private static final UserDefaultThreadPool INSTANCE = new UserDefaultThreadPool();  
    }  
    private UserDefaultThreadPool (){ }
    public static final UserDefaultThreadPool getInstance() {  
        return InstanceHolder.INSTANCE;
    }
    
    private static final int corePoolSize = 2;
    private static final int maxPoolSize = 10;
    private static final long keepAliveTime = 30;
    private static final TimeUnit unit = TimeUnit.SECONDS;
    
    // 构造一个线程池
    private static final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
            corePoolSize, 
            maxPoolSize, 
            keepAliveTime, 
            unit, 
            new LinkedBlockingQueue<Runnable>(),
            new DefaultThreadFactory());
    
    public ThreadPoolExecutor getPool() {
        return threadPool;
    }
    
    public void addTask(Runnable task) {
        getPool().execute(task);
    }
    
    /**
     * 默认的线程工厂
     * <br/>
     * 代码来自JDK代码java.util.concurrent.Executors.DefaultThreadFactory
     * 只是改了线程的名称前缀：pool-user-编号-thread- (默认的名称前缀为：pool-编号-thread-)
     * @author liuy
     *
     */
    static class DefaultThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        DefaultThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();
            namePrefix = "pool-user-" +
                          poolNumber.getAndIncrement() +
                         "-thread-";
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                                  namePrefix + threadNumber.getAndIncrement(),
                                  0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }
}
